/**
 *
 */
package io.potato.core.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

/**
 * @author timl
 * created: 2018年11月7日 下午6:19:41
 */
public class DateTimeUtils {

	public static final String DATETIME_FORMAT_PATTERN = "yyyy-MM-dd HH:mm:ss";

	public static final String STRING_FORMAT_PATTERN = "yyyyMMddHHmmss";

	public static final String DATE_FORMAT_PATTERN = "yyyy-MM-dd";

	public static final String MONTH_FORMAT_PATTERN = "yyyyMM";

	public static final String DAY_FORMAT_PATTERN = "yyyyMMdd";

	public static final String TIME_FORMAT_PATTERN = "HH:mm:ss";

	public static final int AM = 0;

	public static final int PM = 1;

	/**
	 * 获得日期格式化对象
	 */
	public static DateTimeFormatter getDateTimeFormat(String pattern) {
		return DateTimeFormatter.ofPattern(pattern);
	}

	/**
	 * 使用默认格式格式化日期
	 */
	public static String formatWithDefaultPattern(LocalDateTime date){
		return formatWithPattern(date, DATETIME_FORMAT_PATTERN);
	}

	/**
	 * 使用默认格式格式化日期
	 */
	public static String formatWithPattern(LocalDateTime date, String pattern){
		return date.format(getDateTimeFormat(pattern));
	}

	/**
	 * 使用默认格式格式化日期
	 */
	public static String formatWithDefaultPattern(LocalDate date){
		return formatWithPattern(date, DATE_FORMAT_PATTERN);
	}

	/**
	 * 使用默认格式格式化日期
	 */
	public static String formatWithPattern(LocalDate date, String pattern){
		return date.format(getDateTimeFormat(pattern));
	}

	/**
	 * 转换字符串日期
	 */
	public static LocalDateTime parseDateTime(String dateStr, String pattern) {
		return LocalDateTime.parse(dateStr, getDateTimeFormat(pattern));
	}

	/**
	 * 转换字符串日期
	 */
	public static LocalDateTime parseDateTime(String dateStr) {
		return parseDateTime(dateStr, DATETIME_FORMAT_PATTERN);
	}

	/**
	 * 转换字符串日期
	 */
	public static LocalDate parseDate(String dateStr, String pattern) {
		return LocalDate.parse(dateStr, getDateTimeFormat(pattern));
	}

	/**
	 * 转换字符串日期
	 */
	public static LocalDate parseDate(String dateStr) {
		return parseDate(dateStr, DATE_FORMAT_PATTERN);
	}

	/**
	 * 获取一天的开始，也就是00点00分00秒
	 *
	 * @param date 指定的日期
	 * @return 一天的开始
	 */
	public static Date getDayStart(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return getDayStart(calendar);
	}

	/**
	 * 获取是上午还是下午，0是上午，1是下午
	 *
	 * @param date 指定的日期
	 * @return 上午还是下午
	 */
	public static int getAmOrPm(Date date){
		GregorianCalendar gc = new GregorianCalendar();
		gc.setTime(date);
		return gc.get(GregorianCalendar.AM_PM);
	}

	/**
	 * 获取一天的开始，也就是00点00分00秒
	 *
	 * @param date 指定的日期
	 * @param calendar 日历对象
	 * @return 一天的开始
	 */
	private static Date getDayStart(Calendar calendar){
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	/**
	 * 获取一个月的开始，也就是当月的1号00点00分00秒
	 *
	 * @param date 指定的日期
	 * @return 一月的开始
	 */
	public static Date getMonthStart(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		return getDayStart(calendar);
	}

	/**
	 * 获取指定的两个日期之间的所有月份
	 *
	 * @param startDate 开始时间
	 * @param endDate 结束时间
	 * @return 月份集合，包括开始和结束当前所在的月份
	 */
	public static List<Integer> getMonthsBetweenDate(Date startDate, Date endDate){

		List<Integer> monthList = new ArrayList<Integer>();

		if(endDate.before(startDate)){
			return monthList;
		}

		Calendar start = Calendar.getInstance();
		start.setTime(startDate);

		Calendar end = Calendar.getInstance();
		end.setTime(endDate);

		start.set(start.get(Calendar.YEAR), start.get(Calendar.MONTH), 1);
		end.set(end.get(Calendar.YEAR), end.get(Calendar.MONTH), 2);

		Calendar curr = start;

		while (curr.before(end)) {
			monthList.add(curr.get(Calendar.MONTH) + 1);
			curr.add(Calendar.MONTH, 1);
		}

		return monthList;
	}

	/**
	 * 获得该月第一天
	 *
	 * @param year
	 * @param month
	 * @return
	 * @throws ParseException
	 */
	public static Date getFirstDayOfMonth(int year, int month) throws ParseException {
		Calendar cal = Calendar.getInstance();
		// 设置年份
		cal.set(Calendar.YEAR, year);
		// 设置月份
		cal.set(Calendar.MONTH, month - 1);
		// 获取某月最小天数
		int firstDay = cal.getActualMinimum(Calendar.DAY_OF_MONTH);
		// 设置日历中月份的最小天数
		cal.set(Calendar.DAY_OF_MONTH, firstDay);
		// 格式化日期
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String firstDayOfMonth = sdf.format(cal.getTime());
		return sdf.parse(firstDayOfMonth);
	}

	/**
	 * 获得该月最后一天
	 *
	 * @param year
	 * @param month
	 * @return
	 * @throws ParseException
	 */
	public static Date getLastDayOfMonth(int year, int month) throws ParseException {
		Calendar cal = Calendar.getInstance();
		// 设置年份
		cal.set(Calendar.YEAR, year);
		// 设置月份
		cal.set(Calendar.MONTH, month - 1);
		// 获取某月最大天数
		int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
		// 设置日历中月份的最大天数
		cal.set(Calendar.DAY_OF_MONTH, lastDay);
		// 格式化日期
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String lastDayOfMonth = sdf.format(cal.getTime());
		return sdf.parse(lastDayOfMonth);
	}

}
